home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Telnet 2.6.1d1 / src / source / ftp / bkgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-13  |  29.7 KB  |  1,114 lines  |  [TEXT/KAHL]

  1. /*    Background procedures for rcp and ftp
  2. *****************************************************************
  3. *    NCSA Telnet for the Macintosh                                *
  4. *                                                                *
  5. *    National Center for Supercomputing Applications                *
  6. *    Software Development Group                                    *
  7. *    152 Computing Applications Building                            *
  8. *    605 E. Springfield Ave.                                        *
  9. *    Champaign, IL  61820                                        *
  10. *                                                                *
  11. *    Copyright (c) 1986-1992,                                    *
  12. *    Board of Trustees of the University of Illinois                *
  13. *****************************************************************
  14. * Revisions:
  15. * 11/86          Tim Krauskopf
  16. * 7/92    Telnet 2.6: added global structures, cleaned up defines   Scott Bulmahn
  17. *
  18. *
  19. */
  20.  
  21.  
  22. #ifdef MPW
  23. #pragma segment FTPServer
  24. #endif
  25.  
  26. #include <stdio.h>
  27. #include <fcntl.h>
  28. #include <string.h>
  29.  
  30. #include <Memory.h>
  31. #include <CType.h>
  32. #include <ToolUtils.h>    /* BYU - for GetIndString() */
  33.  
  34. #include "TelnetHeader.h"
  35. #include "InternalEvents.h"
  36. #include "netevent.proto.h"
  37. #include "menuseg.proto.h"
  38. #include "network.proto.h"
  39. #include "mydnr.proto.h"
  40. #include "macutil.proto.h"
  41. #include "macbinary.h"
  42. #include "binsubs.proto.h"
  43. #include "maclook.proto.h"
  44. #include "bkgr.proto.h"
  45. #include "telneterrors.h"
  46. #include "wind.h"
  47. #include "mainseg.proto.h"
  48. #include "translate.proto.h"
  49. #include "DlogUtils.proto.h"        // For WriteZero proto
  50.  
  51. #include "vsdata.h"
  52. #include "vsinterf.proto.h"
  53.  
  54. extern WindRec *ftplog;
  55. extern TelInfoRec *TelInfo;
  56. extern char *mungbuf;
  57.  
  58. #define PFTP 1
  59. #define PRCP 2
  60. #define PDATA 3
  61. #define HTELNET 23
  62. #define HRSHD 514
  63. #define HFTP 21
  64. #define BUFFERS 8000
  65. #define PATHLEN 256
  66. #define MACBINARY
  67. #define RCPSEGSIZE 512
  68. #define O_RAW O_RDONLY
  69. #define EOLCHAR 13
  70. #define FASCII 0
  71. #define FIMAGE O_RAW
  72. #define FAMODE 0
  73. #define FIMODE 1
  74. #define FMMODE 2            /* Mac Binary, when ready */
  75.  
  76. MBFile
  77.     *mbfp=NULL;
  78.  
  79. char *nextfile;
  80.  
  81. static short fcnt=0;
  82. static  short
  83.     ftpenable=0,                /* is file transfer enabled? */
  84.     rcpenable=0,                /* is rcp enabled? */
  85. /*    ftpdata=-1,                    /* port for ftp data connection */    /* BYU 2.4.16 */
  86. /*    fnum=-1,                    /* port number for incoming ftp */    /* BYU 2.4.16 */
  87.     rsnum=-1,                    /* port number for incoming rshell */
  88.     rserr=-1;                    /* port number for rshd() stderr */
  89.  
  90. static  unsigned char *xs=0L,    /* buffer space for file transfer */
  91.         *pathname=0L,            /* space to keep path names */
  92.         *newfile=0L,            /* current file being received */
  93.         myuser[17],                    /* user name on my machine */
  94.         waitchar;                    /* character waiting for from net */
  95.  
  96. static short 
  97.     curstate = -1,            /* state machine for background processes */
  98.     retstate = 200,            /* to emulate a subroutine call */
  99.     ftpstate = 0,            /* state of the ftp data transfer */
  100.     isdir=0,                /* flag for rcp target pathname */
  101.     waitpos=0,                /* marker for gathering strings from net */
  102.     cnt=0,                    /* number of characters from last netread() */
  103.     fh=0,                    /* file handle when transfer file is open */
  104.     ftpfh=0,                /* file handle for ftp data */
  105.     rc=0,                    /* telnet flag */
  106.     xp=0,                    /* general pointer */
  107.     towrite=0,                /* file transfer pointer */
  108.     len=0;                    /* file transfer length */
  109.  
  110. static long
  111.     filelen=0L;                /* length of current file for transfer */
  112.  
  113. short mainport[NPORTS];        /* BYU 2.4.16 - map FTP data port to main port */
  114. short dataport[NPORTS];        /* BYU 2.4.16 - map FTP main port to data port */
  115. short mainstate[NPORTS];    /* BYU 2.4.16 */
  116. short datastate[NPORTS];    /* BYU 2.4.16 */
  117. short retnstate[NPORTS];
  118.  
  119. ip_port    fileport[NPORTS];
  120.  
  121. static char crfound=0;
  122.  
  123. static short rfstate,
  124.     ftptmode=FAMODE;            /* how to transfer ze file on net */
  125.  
  126. static    ip_addr    portaddr[NPORTS],
  127.                 hishostaddr;
  128. static    ip_port    portremoteport[NPORTS],
  129.                 portlocalport[NPORTS];
  130.                 
  131. unsigned char messs[100];        /* BYU */
  132.  
  133. char    ListingTemplate[256];
  134. CInfoPBRec    theDirectoryState;
  135.  
  136. static    void CRESP(short fnum, short msg_number);
  137. static    short ftpgo( short fnum);
  138.  
  139. void    FTPServerUnload(void) {}
  140.  
  141. void CRESP(short fnum, short msg_number)
  142. {
  143.   GetIndString(messs,MSG_RESOURCE_ID,msg_number+1);
  144.   netpush(fnum);
  145.   netwrite(fnum, &messs[1], (short)messs[0]);
  146. }
  147.  
  148. void ftpmess( char *cp)
  149. {
  150.     short temp;
  151.     temp=strlen(cp);
  152.     if (temp>80 || temp < 1) return;
  153.     VSwrite(ftplog->vs,cp,temp);
  154. }
  155.  
  156. /***********************************************************************/
  157. void StartUpFTP(void)
  158. {
  159.     if (gFTPServerPrefs->ServerState != 0)
  160.         setftp();
  161.     else
  162.         unsetftp();
  163. }
  164.  
  165. void setftp( void)
  166. {
  167.     short fnum,i1;                            /* BYU 2.4.16 */
  168.  
  169. /* set up to receive a telnet connection for ftp commands */
  170.     rfstate = 0;
  171.     ftpstate = 0;
  172.  
  173. /* Listen for FTP if we're not listening already */
  174.  
  175.     for (i1 = 0; i1 < NPORTS; i1++)                                         /* BYU 2.4.16 */
  176.         if (GetPortType(i1) == PFTP)
  177.             break;                                                            /* BYU 2.4.16 */
  178.  
  179.     if (i1 >= NPORTS) {                                /* BYU 2.4.16 - non-SLIP listen */
  180.         fnum = netlisten(HFTP);        /* BYU 2.4.16 - MacTCP listen */
  181.         ftpenable = 1;                                /* BYU 2.4.16 */
  182.  
  183.         if (fnum >= 0) {                            /* BYU 2.4.16 - signal that events should be caught */
  184.             SetPortType(fnum, PFTP);
  185.             dataport[fnum] = -1;                    /* BYU 2.4.16 - no data needed yet */
  186.             mainstate[fnum] = 0;                    /* BYU 2.4.16 */
  187.             datastate[fnum] = 0;                    /* BYU 2.4.16*/
  188.             retnstate[fnum] = 200;                    /* BYU 2.4.16 */
  189.         }                                            /* BYU 2.4.16 */
  190.     }                                                /* BYU 2.4.16 */
  191.  
  192.     strcpy((char *) myuser,"unknown");                /* BYU LSC - set unknown user name */
  193. }
  194.  
  195. void unsetftp( void)
  196. {
  197.     short i1;                            /* BYU 2.4.16 */
  198.  
  199.     rfstate = 0;
  200.     ftpstate = 0;
  201.     for (i1 = 0; i1 < NPORTS; i1++) {    /* BYU 2.4.16 */
  202.         if (GetPortType(i1) == PFTP) {        /* BYU 2.4.16 */
  203.             netclose(i1);                /* BYU 2.4.16 */
  204.             SetPortType(i1, NO_TYPE);            /* BYU 2.4.16 */
  205.             mainstate[i1] = 0;            /* BYU 2.4.16 */
  206.             datastate[i1] = 0;            /* BYU 2.4.16*/
  207.         }                                /* BYU 2.4.16 */
  208.     }                                    /* BYU 2.4.16 */
  209. /*    fnum = -1;                            /* BYU 2.4.16 */
  210.     ftpenable = 0;
  211. }
  212.  
  213.  
  214. #if 0        /* BYU - Converted to STR# resource number 23227 */
  215. /***********************************************************************/
  216. /*
  217. *  resident ftp server -- enables initiation of ftp without a username
  218. *  and password, as long as this telnet is active at the same time
  219. *  Now checks for the need of passwords.
  220. */
  221.  
  222. static char *messs[] = {
  223.                         "220 Macintosh Resident FTP server, ready \015\012",
  224.                         "451 Error in processing list command \015\012",
  225.                         "221 Goodbye \015\012",                        /*2*/
  226.                         "200 This space intentionally left blank <   > \015\012",
  227.                         "150 Opening connection \015\012",
  228.                         "226 Transfer complete \015\012",            /*5*/
  229.                         "200 Type set to A, ASCII transfer mode \015\012",
  230.                         "200 Type set to I, binary transfer mode \015\012",
  231.                         "500 Command not understood \015\012",        /*8*/
  232.                         "200 Okay \015\012",
  233.                         "230 User logged in \015\012",
  234.                         "550 File not found \015\012",                /*11*/
  235.                         "501 Directory not present or syntax error\015\012",
  236.                         "250 Chdir okay\015\012",
  237.                         "257 \"",
  238.                         "\" is the current directory \015\012",        /*15*/
  239.                         "501 File not found \015\012",
  240.                         "504 Parameter not accepted, not implemented\015\012",
  241.                         "200 Stru F, file structure\015\012",
  242.                         "200 Mode S, stream mode\015\012",        /*19*/
  243.                         "202 Allocate and Account not required for this server\015\012",
  244.                         "501 Cannot open file to write, check for valid name\015\012",
  245.                         "530 USER and PASS required to activate me\015\012",
  246.                         "331 Password required\015\012",      /*23 */
  247.                         "530 Login failed\015\012",
  248.                         "200 MacBinary Mode enabled\015\012",
  249.                         "200 MacBinary Mode disabled\015\012",  /*26 */
  250.                         "552 Disk write error, probably disk full\015\012",
  251.                         "214-NCSA Telnet FTP server, supported commands:\015\012",
  252.                         "    USER  PORT  RETR  ALLO  PASS  STOR  CWD  XCWD  XPWD  LIST  NLST\015\012",
  253.                         "    HELP  QUIT  MODE  TYPE  STRU  ACCT  NOOP  MACB\015\012",  /*30*/
  254.                         "    MACB is MacBinary and must be done with TYPE I\015\012",
  255.                         "214 Direct comments and bugs to telbug@ncsa.uiuc.edu\015\012",
  256.                         "200 Type set to I, binary transfer mode [MACBINARY ENABLED]\015\012",                /* 33 */
  257.                         "200 Type set to I, binary transfer mode [macbinary disabled]\015\012",
  258.                 ""};
  259.  
  260. #endif
  261.  
  262. /* open the FTP data connection to the remote host */
  263. short ftpgo( short fnum)
  264. {
  265.     short    ftpdata;
  266.  
  267.     netfromport(20);                 /* ftp data port */
  268.     ftpdata = netxopen(portaddr[fnum],fileport[fnum], 15);
  269.     mainport[ftpdata] = fnum;
  270.     dataport[fnum] = ftpdata;
  271.     return(ftpdata);
  272. }
  273.  
  274. void rftpd
  275.   (
  276.     short code,                                /* BYU 2.4.16 */
  277.     short fnum                                /* BYU 2.4.16 */
  278.   )
  279. {
  280.     ip_port    fdport;
  281.     short    ftpdata, i, append = 0;
  282.     char    tempp[256], theDir[256];
  283.     char updir[4];                        /* JMB 2.6 */
  284.     
  285.     if (!ftpenable)
  286.         return;
  287.  
  288.     netpush(fnum);
  289.  
  290.     rfstate = mainstate[fnum];                /* BYU 2.4.16 */
  291.     ftpstate = datastate[fnum];                /* BYU 2.4.16 */
  292.     retstate = retnstate[fnum];                /* BYU 2.4.16 */
  293.     fdport = fileport[fnum];                /* BYU 2.4.16 */
  294.  
  295.     switch (rfstate) {
  296.         case 0:
  297.             if (code != CONOPEN) 
  298.                 break;
  299.             ftptmode = FAMODE;
  300.             netputevent(USERCLASS,FTPCOPEN,-1,0);
  301.             if (!xs) xs=(unsigned char *)NewPtrClear(BUFFERS+10);    /* BYU LSC */
  302.             if (!pathname) pathname=(unsigned char *)NewPtrClear(PATHLEN);
  303.             if (!newfile) newfile=(unsigned char *)NewPtrClear(PATHLEN);
  304.             if (!xs || !pathname || !newfile)    /* no memory for ftp names */
  305.                 {
  306.                 DoError(114 | MEMORY_ERRORCLASS, LEVEL3, NULL);
  307.                 quit();                    // Should we really quit?
  308.                 }    
  309.         
  310.             rfstate = 1;                /* drop through */
  311.         case 1:
  312.             CRESP(fnum,0);                            /* BYU 2.4.16 */
  313.             netgetftp(fnum, &portaddr[fnum], &portlocalport[fnum], &portremoteport[fnum]);        /* BYU 2.4.16 - get default ftp information */
  314.             hishostaddr = portaddr[fnum];
  315.             fdport = portremoteport[fnum];
  316.  
  317.             waitpos = 0; waitchar = '\012';
  318.             rfstate = 50;               /* note skips over */
  319.             if ((gFTPServerPrefs->ServerState == 2)) 
  320.                 retstate = 3;                /* check pass */
  321.             else
  322.                 retstate = 5;                /* who needs one ? */
  323.             break;
  324.         case 3:                /* check for passwords */
  325.         case 4:
  326.             waitpos = 0;  waitchar = '\012';
  327.             rfstate = 50;  
  328.             if (!strncmp("USER",(char *) xs,4)) {    /* BYU LSC */
  329.                 if (strlen((char *) xs) < 6)        /* BYU LSC - make sure blank name stays blank */
  330.                     xs[5] = myuser[0] = 0;
  331.                 strncpy((char *) myuser,(char *) &xs[5],16);        /* BYU LSC - keep user name */
  332.                 FTPLogUserLoggingIn();
  333.                 CRESP(fnum,23);                                        /* BYU 2.4.16 */
  334.                 retstate = 4;        /* wait for password */
  335.                 break;
  336.             }
  337.             if (!strncmp("PASS",(char *) xs,4)) {                    /* BYU LSC */
  338.                 if (Scheckpass((char *) myuser,(char *) &xs[5])) {    /* BYU LSC */
  339.                     ftpmess("FTP password OK - logged in\015\012");
  340.                     CRESP(fnum,10);                                    /* BYU 2.4.16 */
  341.                     retstate = 5;
  342.                 }
  343.                 else {
  344.                     ftpmess("FTP password failed - access denied\015\012");
  345.                     CRESP(fnum,24);                                    /* BYU 2.4.16 */
  346.                     retstate = 3;
  347.                 }
  348.                 break;
  349.             }
  350.             if (!strncmp("QUIT",(char *) xs,4)) {    /* BYU LSC */
  351.                 CRESP(fnum,2);                        /* BYU 2.4.16 */
  352.                 cnt = -1;
  353.             }
  354.             else {
  355.                 CRESP(fnum,22);        /* BYU 2.4.16 */
  356.             }
  357.             retstate = 3;            /* must have password first */
  358.             break;                
  359.                 
  360. /* interpret commands that are received from the other side */
  361.             
  362.         case 5:
  363.  
  364. /* set to a safe state to handle recursion, wait for another command line from client */
  365.             rfstate = 50;
  366.             retstate = 5;
  367.             waitchar = '\012';
  368.             waitpos = 0;
  369.  
  370.             if (!strncmp((char *) xs,"LIST",4) || !strncmp((char *) xs,"NLST",4)) {    /* BYU LSC */
  371.                 if ((strlen((char *) xs) < 6) || xs[5] == '.')        /* BYU LSC */
  372.                     strcpy((char *) xs,"LIST *");                    /* BYU LSC */
  373.                 strcpy(ListingTemplate, (char *) &xs[5]);
  374.                 nextfile = firstname(ListingTemplate, TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, &theDirectoryState);    /* find first name */
  375.                 if (nextfile == NULL) {
  376.                     CRESP(fnum,16);                /* BYU 2.4.16 */
  377.                 }
  378.                 else {
  379.                     Str255    tempstr;
  380.                     char    tempstr2[256];
  381.                     ftpdata = ftpgo(fnum);                /* BYU 2.4.16 - open the connection */
  382.                     fdport = portremoteport[fnum]; /* BYU 2.4.16 - reset to def */
  383.  
  384.                     if (ftpdata >= 0)
  385.                         SetPortType(ftpdata, PDATA);
  386.                     ftpstate = 40;        /* ready to transmit */
  387.                     CRESP(fnum,4);                            /* BYU 2.4.16 */
  388.                     PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, tempstr);
  389.                     PtoCstr(tempstr);
  390.                     sprintf(tempstr2, "FTP Sending Directory %s\015\012", (char *)tempstr);
  391.                     ftpmess(tempstr2);
  392.                 }
  393.             }
  394.             else if (!strncmp((char *) xs,"CWD",3)) {    /* BYU LSC */
  395.                 if (ChangeDirectory(&(TelInfo->DefaultDirDirID), &(TelInfo->DefaultDirVRefNum), (char *) &xs[4])) {
  396.                     CRESP(fnum,12);                        /* BYU 2.4.16 */
  397.                 }
  398.                 else {                        /* success */
  399.                     CRESP(fnum,13);            /* BYU 2.4.16 */
  400.                 }
  401.             }
  402.             else if (!strncmp((char *) xs,"CDUP",4)) {        /* JMB 2.6 */
  403.                 strcpy(updir, "..");                        /* JMB 2.6 */
  404.                 if (ChangeDirectory(&(TelInfo->DefaultDirDirID), &(TelInfo->DefaultDirVRefNum), updir)) {                /* JMB 2.6 */
  405.                     CRESP(fnum,12);                            /* JMB 2.6 */
  406.                 }                                            /* JMB 2.6 */
  407.                 else {                                        /* JMB 2.6 */
  408.                     CRESP(fnum,13);                            /* JMB 2.6 */
  409.                 }                                            /* JMB 2.6 */
  410.             }                                                /* JMB 2.6 */
  411.             else if (!strncmp((char *) xs,"STOR",4) || !strncmp((char *) xs,"APPE", 4))
  412.               {
  413.                 short    MBflag;
  414.  
  415.                 if (!strncmp((char *) xs,"APPE", 4)) {
  416.                     if (ftptmode != FASCII) {
  417.                         CRESP(fnum, 35);
  418.                         break;
  419.                         }
  420.                     else
  421.                         append = 1;
  422.                     }
  423.                     
  424.                 /* had to simplify this, else MPW C 3.0/3.1 generates bad code! */
  425.                 if ((!TelInfo->MacBinary) || (ftptmode == FAMODE))
  426.                     MBflag = MB_DISABLE;
  427.                 else
  428.                     MBflag = 0;
  429.                     
  430.                 if (ftptmode == FAMODE)    MBflag |= MB_ISASCII;
  431.                 if (append) MBflag |= MB_APPEND;
  432.                 append = 0;
  433.                 
  434.                 mbfp = MBopen((char *)&xs[5], TelInfo->DefaultDirVRefNum, TelInfo->DefaultDirDirID, (short)(MB_WRITE | MBflag));
  435.                 if (mbfp == 0L)
  436.                   {
  437.                     CRESP(fnum,21);            /* BYU 2.4.16 */
  438.                     break;
  439.                   }
  440.                 else
  441.                     ftpfh = 12;
  442.  
  443.                 ftpstate = 0;
  444.  
  445.                 strncpy((char *) newfile,(char *) &xs[5],PATHLEN-1);    /* BYU LSC */
  446.                 
  447.  
  448.                 ftpdata = ftpgo(fnum);                /* BYU 2.4.16 - open connection */
  449.                 fdport = portremoteport[fnum]; /* BYU 2.4.16 - reset to def */
  450.  
  451.                 if (ftpdata >= 0)
  452.                     SetPortType(ftpdata, PDATA);
  453.  
  454.                 CRESP(fnum,4);        /* BYU 2.4.16 */
  455.  
  456.                 ftpstate = 30;        /* ready for data */
  457.               }
  458.  
  459.             else if (!strncmp((char *) xs,"RETR",4))    /* BYU LSC */
  460.               {
  461.               /* had to simplify this, else MPW C 3.0/3.1 generates bad code! */
  462.                 short
  463.                     MBflag;
  464.                 if ((!TelInfo->MacBinary) || (ftptmode == FAMODE))
  465.                     MBflag = MB_DISABLE;
  466.                 else
  467.                     MBflag = 0;
  468.                     
  469.                 if (ftptmode == FAMODE)    MBflag |= MB_ISASCII;
  470.                 
  471.                 mbfp = MBopen((char *) &xs[5], TelInfo->DefaultDirVRefNum, TelInfo->DefaultDirDirID, MB_READ | MBflag);
  472.                 
  473.                 if (mbfp == 0L) {
  474.                     CRESP(fnum,11);                        /* BYU 2.4.16 */
  475.                     break;
  476.                 }
  477.                 ftpfh = 12;
  478.  
  479.                 strncpy((char *) newfile,(char *) &xs[5],PATHLEN-1);    /* BYU LSC */
  480.  
  481.                 PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, (StringPtr) theDir);
  482.                 PtoCstr((StringPtr) theDir);
  483.                 sprintf(tempp,"remote <-- %s/%s\015\012",theDir,newfile);
  484.                 ftpmess(tempp);
  485.  
  486.                 ftpdata = ftpgo(fnum);                /* BYU 2.4.16 - open connection */
  487.                 fdport = portremoteport[fnum];
  488.  
  489.                 ftpstate = 20;        /* ready for data */
  490.                 if (ftpdata >= 0)
  491.                     SetPortType(ftpdata, PDATA);
  492.  
  493.                 CRESP(fnum,4);                            /* BYU 2.4.16 */
  494.               }
  495.             else if (!strncmp((char *) xs,"TYPE",4)) {    /* BYU LSC */
  496.                 if (toupper(xs[5]) == 'I') {
  497.                     ftptmode = FIMODE;
  498.                     if (TelInfo->MacBinary) {
  499.                         CRESP(fnum,33);                    /* BYU 2.4.16 - Binary on, MACB ON */
  500.                         }
  501.                     else {
  502.                         CRESP(fnum,34);                    /* BYU 2.4.16 - Binary on, MACB off */
  503.                         }
  504.                 }
  505.                 else if (toupper(xs[5]) == 'A') {
  506.                     ftptmode = FAMODE;
  507.                     CRESP(fnum,6);                    /* BYU 2.4.16 */
  508.                     }
  509.                 else {
  510.                     CRESP(fnum,17);                    /* BYU 2.4.16 */
  511.                 }
  512.  
  513.             }
  514.             else if (!strncmp((char *) xs,"MACB",4)) {    /* BYU LSC */
  515.                 if (toupper(xs[5]) == 'E') {
  516.                     TelInfo->MacBinary = 1;
  517.                     CRESP(fnum,25);                    /* BYU 2.4.16 */
  518.                 }
  519.                 else {
  520.                     TelInfo->MacBinary = 0;
  521.                     CRESP(fnum,26);                    /* BYU 2.4.16 */
  522.                 }
  523.                 DisplayMacBinary();            /* post an event ? */
  524.             }
  525.             else if (!strncmp((char *) xs,"PORT",4)) {    /* BYU LSC */
  526. /*    get the requested port number from the command given */
  527.                 ip_addrbytes    tempaddr;
  528.                 short            tempshorts[6];
  529.                 sscanf((char *) &xs[5],"%d,%d,%d,%d,%d,%d",
  530.                     &tempshorts[0],&tempshorts[1],
  531.                     &tempshorts[2],&tempshorts[3],
  532.                     &tempshorts[4],&tempshorts[5]);
  533.                 tempaddr.a.byte[0] = (char) tempshorts[0];
  534.                 tempaddr.a.byte[1] = (char) tempshorts[1];
  535.                 tempaddr.a.byte[2] = (char) tempshorts[2];
  536.                 tempaddr.a.byte[3] = (char) tempshorts[3];
  537.                 portaddr[fnum] = tempaddr.a.addr;
  538.                 portlocalport[fnum] = tempshorts[4]*256+tempshorts[5];
  539.                 fdport = portlocalport[fnum];
  540.                 CRESP(fnum,3);                            /* BYU 2.4.16 */
  541.             }
  542.             else if (!strncmp((char *) xs,"QUIT",4)) {    /* BYU LSC */
  543.                 CRESP(fnum,2);                            /* BYU 2.4.16 */
  544.                 rfstate = 60;
  545.                 netputuev(CONCLASS,CONDATA,fnum,0);    /* post back to me */
  546.             }
  547.             else if (!strncmp((char *) xs,"XPWD",4) || !strncmp((char *) xs,"PWD",3)) {    /* BYU LSC */
  548.                 CRESP(fnum,14);                        /* BYU 2.4.16 - start reply */
  549.                 PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, (StringPtr) xs);
  550.                 PtoCstr((StringPtr) xs);
  551.                 netwrite(fnum,(char *) xs,strlen((char *) xs));    /* BYU LSC - write dir name */
  552.                 CRESP(fnum,15);                        /* BYU 2.4.16 - finish reply */
  553.             }
  554.             else if (!strncmp((char *) xs,"USER",4)) {    /* BYU LSC */
  555.                 if (strlen((char *) xs) < 6)            /* BYU LSC - make sure blank name stays blank */
  556.                     xs[5] = myuser[0] = 0;
  557.                 strncpy((char *) myuser,(char *) &xs[5],16);    /* BYU LSC - keep user name */
  558.                 FTPLogUserLoggingIn();
  559.                 /* confirm log in without password */
  560.                 CRESP(fnum,10);                            /* BYU 2.4.16 */
  561.             }
  562.             else if (!strncmp((char *) xs,"STRU",4)) {    /* BYU LSC - only one stru allowed */
  563.                 if (xs[5] == 'F') {
  564.                     CRESP(fnum,18); }                    /* BYU 2.4.16 */
  565.                 else {
  566.                     CRESP(fnum,17); }                    /* BYU 2.4.16 */
  567.             }
  568.             else if (!strncmp((char *) xs,"MODE",4)) {    /* BYU LSC - only one mode allowed */
  569.                 if (xs[5] == 'S') {
  570.                     CRESP(fnum,19); }                    /* BYU 2.4.16 */
  571.                 else {
  572.                     CRESP(fnum,17); }                    /* BYU 2.4.16 */
  573.             }
  574.             else if (!strncmp((char *) xs,"ALLO",4) || !strncmp((char *) xs,"ACCT",4)) {    /* BYU LSC */
  575.                 CRESP(fnum,20); }                        /* BYU 2.4.16 */
  576.             else if (!strncmp((char *) xs,"HELP",4)) {    /* BYU LSC */
  577.                 for (i=28; i<33; i++) {
  578.                     CRESP(fnum,i); }                    /* BYU 2.4.16 */
  579.             }
  580.             else if (!strncmp((char *) xs,"NOOP",4)) {        /* BYU LSC */
  581.                 CRESP(fnum,9); }                            /* BYU 2.4.16 */
  582.             else if (!strncmp((char *) xs,"SYST",4)) {    // JMB 2.6
  583.                   netpush(fnum);                        // JMB 2.6
  584.                   netwrite(fnum, "225 MACOS System Version:\015\012", 27);    // JMB 2.6
  585.                     }    // JMB 2.6
  586.             else {            /* command not understood */
  587.                 CRESP(fnum,8);                                 /* BYU 2.4.16 */
  588.             }
  589.  
  590.             break;
  591.  
  592. /*    subroutine to wait for a particular character */
  593.         case 50:
  594.             while (0 < (cnt = netread(fnum,&xs[waitpos],1))) {
  595.                 if (xs[waitpos] == waitchar) {
  596.                     rfstate = retstate;
  597.  
  598.                     while (xs[waitpos] < 33)        /* find end of string */
  599.                         waitpos--;
  600.                     xs[++waitpos] = '\0';            /* put in terminator */
  601.  
  602.                     for (i=0; i<4; i++)                /* want upper case */
  603.                         xs[i] = toupper(xs[i]);
  604.  
  605.                     break;
  606.                 }
  607.                 else
  608.                     waitpos += cnt;
  609.  
  610.             }
  611.             break;
  612.  
  613.         case 60:                    /* wait for message to get through */
  614.                                     /* or connection is broken */
  615. /*            printf("                  %d,%d",netpush(fnum),netest(fnum));*/
  616.             if (!netpush(fnum) || netest(fnum))
  617.                 cnt = -1;
  618.             else
  619.                 netputuev(CONCLASS,CONDATA,fnum,0);    /* post back to me */
  620.             break;
  621.  
  622.         default:
  623.             break;
  624.  
  625.     }
  626.  
  627.     if (cnt < 0) {
  628.         if (mbfp) {
  629.             MBclose( mbfp );
  630.             mbfp = NULL;
  631.         }
  632.         ftpdata = dataport[fnum];                    /* BYU 2.4.16 */
  633.         if (ftpdata > 0) {
  634.             netclose(ftpdata);
  635.             netputevent(USERCLASS,FTPEND,-1,0);
  636.             dataport[fnum] = -1;                    /* BYU 2.4.16 */
  637.             mainport[ftpdata] = -1;                    /* BYU 2.4.16 */
  638.         }
  639.         rfstate = 100;
  640.         ftpstate = 0;
  641.         cnt = 0;
  642.         netclose(fnum);
  643.         SetPortType(fnum, NO_TYPE);
  644.         netputevent(USERCLASS,FTPCLOSE,-1,0);
  645. #if 0                                                /* BYU 2.4.16 */
  646.         fnum = -1;
  647.         ftpdata = -1;
  648. #endif                                                /* BYU 2.4.16 */
  649.         setftp();                /* reset it */
  650.     }
  651.  
  652.     mainstate[fnum] = rfstate;                        /* BYU 2.4.16 */
  653.     datastate[fnum] = ftpstate;                        /* BYU 2.4.16 */
  654.     retnstate[fnum] = retstate;                        /* BYU 2.4.16 */
  655.     fileport[fnum] = fdport;                        /* BYU 2.4.16 */
  656.  
  657. }
  658.  
  659. /*    important note:  for Sfread, nwant must be 256 bytes LARGER than the amount
  660.     which will probably be read from the connection.
  661.     Sfread will stop anywhere from 0 to 256 bytes short of filling nwant
  662.     number of bytes. */
  663.     
  664. long Sfread( short pnum, char *buf, long nwant)
  665. {
  666.     long    i, ndone, lim;
  667.     char    *p, *q;
  668.  
  669.     if (nwant < 1024)
  670.         return(-1);
  671.  
  672.     ndone = 0;
  673.  
  674.     while (ndone < nwant - 1024) {
  675.  
  676.         if (0 >= (lim = netread(pnum,mungbuf,1024))) {
  677.             if (ndone || !lim)            /* if this read is valid, but no data */
  678.                 return(ndone);
  679.             else
  680.                 return(-1);                /* if connection is closed for good */
  681.         }
  682.  
  683.         p = mungbuf;
  684.         q = (char *) buf + ndone;
  685.  
  686. /*        printf("\012 lim=%d done=%d want=%d",lim,ndone,nwant);
  687.         n_row();
  688. */
  689.         for (i=0; i < lim; i++) {
  690.  
  691.             if (crfound) {
  692.                 if (*p == 10)
  693.                     *q++ = EOLCHAR;
  694.                 else if (*p == 0)
  695.                     *q++ = 13;            /* CR-NUL means CR */
  696.                 crfound = 0;
  697.             }
  698.             else if (*p == 13)
  699.                 crfound = 1;
  700.             else
  701.                 if (gFTPServerPrefs->DoISOtranslation)
  702.                 {
  703.                     *q++ = (char) ftp_iso_mac((unsigned char *)p);        /* transform to mac */
  704.                 }
  705.                 else
  706.                     *q++ = *p;                /* copy the char */
  707.  
  708.             p++;
  709.         }
  710.  
  711.         ndone = q-buf;                    /* count chars ready */
  712.     }
  713.  
  714.     return(ndone);
  715. }
  716.  
  717. /***************************************************************************/
  718. /*  Sfwrite
  719. *   Write an EOL translated buffer into netwrite.
  720. *   Returns the number of bytes which were processed from the incoming
  721. *   buffer.  Uses its own 1024 byte buffer for the translation (with Sfread).
  722. */
  723.  
  724. long Sfwrite( short pnum, void *buf, long nsrc)
  725. {
  726.     long    i,ndone,nout,lim;
  727.     char    *p,*q;
  728.  
  729.     ndone = 0;
  730.  
  731.     while (ndone < nsrc) {
  732.  
  733.         if (0 > ( i = netroom(pnum)))
  734.             return(-1);
  735.  
  736.         if (i < 1024)                    /* not enough room to work with */
  737.             return(ndone);
  738.  
  739. /*    process up to 512 source bytes for output (could produce 1K bytes out) */
  740.         if (nsrc - ndone > 512)
  741.             lim = 512;
  742.         else
  743.             lim = nsrc-ndone;
  744.  
  745.         p = (char *) buf + ndone;                /* where to start this block */
  746.         q = mungbuf;                    /* where munged stuff goes */
  747.         for (i=0; i < lim; i++) {
  748.             if (*p == EOLCHAR) {
  749.                 *q++ = 13;
  750.                 *q++ = 10;
  751.                 p++;
  752.             }
  753.             else
  754.                 if (gFTPServerPrefs->DoISOtranslation)
  755.                 {
  756.                     *q++ = (char) ftp_mac_iso((unsigned char *)p);        /* transform to ISO */
  757.                     p++;
  758.                 }
  759.                 else
  760.                     *q++ = *p++;
  761.         }
  762.         ndone += lim;                    /* # of chars processed */
  763.         nout = q-mungbuf;                /* # of chars new */
  764.  
  765.         if ( nout != netwrite(pnum,mungbuf,nout) )        /* Some error in Sfwrite */
  766.             DoError (201 | RESOURCE_ERRORCLASS, LEVEL1, NULL);
  767.  
  768.     }
  769.  
  770.     return(ndone);
  771. }
  772.  
  773.  
  774. /*    FTP receive and send file functions */
  775.  
  776. void ftpd
  777.   (
  778.     short code,
  779.     short ftpdata                            /* BYU 2.4.16 */
  780.   )
  781. {
  782.     short fnum = mainport[ftpdata];        /* BYU 2.4.16 */
  783.     short i,a;
  784.     char tempp[256];
  785.     char theDir[256];
  786.  
  787. /*    if (curcon != ftpdata)                /* BYU 2.4.16 - wrong event, was for someone else */
  788. /*        return;                            /* BYU 2.4.16 */
  789.  
  790.     ftpstate = datastate[fnum];            /* BYU 2.4.16 */
  791.  
  792.     switch (ftpstate) {
  793.         default:
  794.             break;
  795.  
  796.         case 40:                /* list file names in current dir */
  797.  
  798.             if (code == CONFAIL)    /* something went wrong */
  799.                 fcnt = -1;
  800.             if (code != CONOPEN)     /* waiting for connection to open */
  801.                 break;
  802.             
  803.             ftpstate = 41;
  804.  
  805. /*
  806. *  send the "nextfile" string and then see if there is another file
  807. *  name to send
  808. */
  809.         case 41:
  810.             netputuev(SCLASS,FTPACT,ftpdata,0);
  811.             netpush(ftpdata);
  812.             strcpy(tempp,nextfile);                    /* BYU 2.4.13 */
  813.             strcat(tempp,"\015\012");                /* BYU 2.4.13 */
  814.             i = strlen(tempp);                        /* BYU 2.4.13 */
  815.             if (gFTPServerPrefs->DoISOtranslation)
  816.                 trbuf_mac_ftp((unsigned char *)tempp, i);        /* transform to ISO */ //PETERL?
  817.             if (i != netwrite(ftpdata,tempp,i)) {    /* BYU 2.4.13 */
  818.                 CRESP(fnum,1);                        /* BYU 2.4.16 */
  819.                 fcnt = -1;
  820.                 break;
  821.             }
  822. /*            netwrite(ftpdata,"\015\012",2);            /* BYU 2.4.13 */
  823.  
  824.             if (NULL == (nextfile = nextname(ListingTemplate, &theDirectoryState))) {    /* normal end */
  825.                 ftpstate = 22;               /* push data through */
  826.             }
  827.             break;
  828.             
  829.         case 30:
  830.             if (code == CONFAIL)    /* something went wrong */
  831.                 fcnt = -1;
  832.             if (code != CONOPEN)    /* waiting for connection to open */
  833.                 break;
  834.             ftpstate = 31;
  835.             crfound = 0;
  836.             len = xp = 0;
  837.             filelen = 0L;
  838.             PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, (StringPtr) theDir);
  839.             PtoCstr((StringPtr) theDir);
  840.             sprintf(tempp,"remote --> %s/%s\015\012",theDir,newfile);
  841.             ftpmess(tempp);
  842.             netputevent(USERCLASS,FTPBEGIN,-2,0);
  843.             
  844.         case 31:
  845. /*
  846. * file has already been opened, take everything from the connection
  847. * and place into the open file: ftpfh
  848. */
  849.             do {
  850.             /* wait until xs is full before writing to disk */
  851.                 if (len <= 2000) {
  852.  
  853.                     if (xp) {
  854.                         if (0 > MBwrite(mbfp, xs, xp)) {
  855.                             DoError (202 | RESOURCE_ERRORCLASS, LEVEL1, NULL);
  856.  
  857.                             MBclose( mbfp);            /* Close on Disk Full Error */
  858.                             ftpstate=22;
  859.                             CRESP(fnum,27);                /* BYU 2.4.16 */
  860.                             ftpmess((char *) messs);    /* BYU LSC */
  861.                             if( (a = netclose(ftpdata)) !=0 ) 
  862.                                 DoError (108 | NET_ERRORCLASS, LEVEL1, NULL);
  863.                             fcnt = -1;
  864.                             mbfp=NULL;
  865.                             break;
  866.                         }
  867.                         xp = 0;
  868.                     }
  869.                     len = BUFFERS;        /* expected or desired len to go */
  870.                 }
  871.  
  872.                 if (ftptmode == FAMODE)
  873.                     fcnt = Sfread(ftpdata,(char *) &xs[xp],len);    /* BYU LSC */
  874.                 else
  875.                     fcnt = netread(ftpdata,&xs[xp],len);
  876.  
  877.                 if (fcnt >= 0) {
  878.                     len -= fcnt;
  879.                     xp += fcnt;
  880.                     filelen += fcnt;
  881.                 }
  882.  
  883.                 if (fcnt < 0) {
  884.                     if (0 > MBwrite( mbfp, xs, xp)) {
  885.                         CRESP(fnum,27);            /* BYU 2.4.16 */
  886.                         MBclose( mbfp);            /* Close file on error */
  887.                         break;
  888.                     }
  889.                     MBclose( mbfp );
  890.                     ftpfh = 0;
  891.                     CRESP(fnum,5);                    /* BYU 2.4.16 */
  892.                 }
  893.  
  894.             } while (fcnt > 0);
  895.             break;
  896.  
  897.         case 20:
  898.  
  899.             if (code == CONFAIL)    /* something went wrong */
  900.                 fcnt = -1;
  901.             if (code != CONOPEN)    /* waiting for connection to open */
  902.                 break;
  903.             ftpstate = 21;
  904.             filelen = MBsize( mbfp );
  905.             towrite = 0;
  906.             xp = 0;
  907.             netputevent(USERCLASS,FTPBEGIN,-1,0);
  908.  
  909.         case 21:
  910. /*
  911. *  transfer file(s) to the other host via ftp request
  912. *  file is already open = ftpfh
  913. */
  914.             netputuev(SCLASS,FTPACT,ftpdata,0);
  915.         
  916.             if (towrite <= xp) {
  917.  
  918.                 i = BUFFERS;
  919.                 towrite = MBread( mbfp, xs, i);
  920.                 xp = 0;
  921.             }
  922.  
  923.             if (towrite <= 0 || netest(ftpdata)) {        /* we are done */
  924.                 ftpstate = 22;
  925.                 break;
  926.             }
  927.  
  928.             if (ftptmode == FAMODE)
  929.                 i = Sfwrite(ftpdata,&xs[xp],towrite-xp);
  930.             else
  931.                 i = netwrite(ftpdata,&xs[xp],towrite-xp);
  932.  
  933.  
  934. /*            printf(" %d %d %d \012",i,xp,towrite);
  935.             n_row(); */
  936.  
  937.             if (i > 0) {
  938.                 xp += i;
  939.                 filelen -= i;
  940.                 if (filelen < 0L)
  941.                     filelen = 0L;
  942.             }
  943.  
  944.             break;
  945.  
  946.         case 22:        /* wait for data to be accepted */
  947.             netputuev(SCLASS,FTPACT,ftpdata,0);
  948.  
  949.             fcnt = netpush(ftpdata);        /* will go negative on err */
  950.             if (!fcnt || netest(ftpdata))
  951.                 fcnt = -1;
  952.             if (fcnt < 0) {
  953.                 CRESP(fnum,5);                /* BYU 2.4.16 */
  954.             }
  955.             break;
  956.  
  957.         case 0:
  958.             break;
  959.  
  960.     }  /* end of switch */
  961.  
  962. /*    after reading from connection, if the connection is closed, reset up shop. */
  963.     if (fcnt < 0) {
  964.         if (mbfp) {
  965.             MBclose( mbfp );
  966.             mbfp = NULL;
  967.         }
  968.         ftpstate = 0;
  969.         fcnt = 0;
  970.         if (ftpdata >= 0) {
  971.             netclose(ftpdata);
  972.             netputevent(USERCLASS,FTPEND,-1,0);
  973. /*            ftpdata = -1;                        /* BYU 2.4.16 */
  974.             mainport[ftpdata] = -1;                /* BYU 2.4.16 */
  975.             dataport[fnum] = -1;                /* BYU 2.4.16 */
  976.         }
  977.     }
  978.  
  979.     datastate[fnum] = ftpstate;            /* BYU 2.4.16 */
  980.  
  981. }
  982.  
  983.  
  984. /* Sftpname and Sftpuser and Sftphost
  985. *  record the name of the file being transferred, to use in the status
  986. *  line updates
  987. */
  988.  
  989. void Sftpname
  990.   (
  991.     char *s
  992.   )
  993.   {
  994.     strcpy(s, (char *) newfile);    /* BYU LSC */
  995.   }
  996.  
  997. ip_addr Sftphost(void)
  998.   {
  999.     return(hishostaddr);
  1000.   }
  1001.  
  1002. void Sftpstat
  1003.   (
  1004.     long *byt
  1005.   )
  1006.     {
  1007.     
  1008. //    if (ftptmode != FAMODE && TelInfo->MacBinary)    /* MacBinary transfer */
  1009. //        *byt = -1;
  1010. //    else
  1011.         *byt = filelen;
  1012.  
  1013. }
  1014.  
  1015. void FTPLogUserLoggingIn(void)
  1016. {
  1017.     ftpmess("FTP user ");
  1018.     ftpmess((char *) myuser);
  1019.     ftpmess(" logging in\015\012");
  1020. }
  1021.  
  1022. /****************************************************************************/
  1023. /* Sencompass - Compute the encrypted password */
  1024. void Sencompass(char *ps, char *en)
  1025. {
  1026.     short    i,ck;
  1027.     char    *p,c;
  1028.  
  1029.     ck = 0;
  1030.     p = ps;
  1031.     while (*p)                /* checksum the string */
  1032.         ck += *p++;
  1033.  
  1034.     c = ck;
  1035.  
  1036.     for (i=0; i<10; i++) {
  1037.         *en =  (((*ps ^ c) | 32) & 127);     /* XOR with checksum */
  1038.         if (*ps)
  1039.             ps++;
  1040.         else
  1041.             c++;        /* to hide length */
  1042.         en++;
  1043.     }
  1044.  
  1045.     *en = 0;
  1046. } /* Sencompass */
  1047.  
  1048. /****************************************************************************/
  1049. /* Scompass - compute and check the encrypted password */
  1050. Boolean Scompass(char *ps, char *en)
  1051. {
  1052.     short    ck;
  1053.     char    *p,c;
  1054.  
  1055.     ck = 0;
  1056.     p = ps;
  1057.     while (*p)                /* checksum the string */
  1058.         ck += *p++;
  1059.  
  1060.     c = ck;
  1061.  
  1062.     while (*en) {
  1063.         if ((((*ps ^ c) | 32) & 127) != *en)    /* XOR with checksum */
  1064.             return(FALSE);
  1065.         if (*ps)
  1066.             ps++;
  1067.         else
  1068.             c++;            /* increment checksum to hide length */
  1069.         en++;
  1070.     }
  1071.  
  1072.     return(TRUE);
  1073. }
  1074.  
  1075. /****************************************************************************/
  1076. /*  Scheckpass - Check the password file for the user, password combination */
  1077. Boolean Scheckpass(char *us, char *ps)
  1078. {
  1079.     FTPUser        **FTPUhdl;
  1080.     Str255        scratchPstring;
  1081.     CInfoPBRec    theInfo;
  1082.     
  1083.     strcpy((char *)scratchPstring, us);
  1084.     CtoPstr((char *)scratchPstring);
  1085.     
  1086.     UseResFile(TelInfo->SettingsFile);
  1087.     FTPUhdl = (FTPUser **)Get1NamedResource(FTPUSER, scratchPstring);
  1088.     if (ResError()) return(FALSE);        // User not found
  1089.     
  1090.     HLock((Handle)FTPUhdl);
  1091.     BlockMove((**FTPUhdl).EncryptedPassword, scratchPstring,
  1092.                 Length((**FTPUhdl).EncryptedPassword)+1);
  1093.     PtoCstr(scratchPstring);
  1094.     
  1095.     if (Scompass(ps, (char *)scratchPstring)) {        // Password matches
  1096.         TelInfo->DefaultDirDirID = (**FTPUhdl).DefaultDirDirID;
  1097.         TelInfo->DefaultDirVRefNum = VolumeNameToRefNum((**FTPUhdl).DefaultDirVolName);
  1098.         WriteZero((Ptr)&theInfo, sizeof(CInfoPBRec));
  1099.         theInfo.dirInfo.ioVRefNum = TelInfo->DefaultDirVRefNum;
  1100.         theInfo.dirInfo.ioDrDirID = TelInfo->DefaultDirDirID;
  1101.         theInfo.dirInfo.ioNamePtr = scratchPstring;
  1102.         theInfo.dirInfo.ioFDirIndex = -1;        // Only give me the Directory Info
  1103.         if (PBGetCatInfoSync(&theInfo) != noErr) {
  1104.             TelInfo->DefaultDirDirID = 2;
  1105.             TelInfo->DefaultDirVRefNum = -1;
  1106.             }
  1107.         ReleaseResource((Handle)FTPUhdl);
  1108.         return(TRUE);
  1109.         }
  1110.     
  1111.     ReleaseResource((Handle)FTPUhdl);
  1112.     return(FALSE);                                    // Password was no good
  1113. }
  1114.